package net.biaji.android.cmwrap.services;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import net.biaji.android.cmwrap.Logger;

public class InnerSocketBuilder {

	private String proxyHost = "10.0.0.172";
	private int proxyPort = 80;
	private String target = "";

	private Socket innerSocket = null;

	private boolean isConnected = false;

	private long starTime = System.currentTimeMillis();
	
	private final String TAG = "InnerSocketBuilder";
	private final String UA = "Wang UA";
	
	FutureTask<Socket> future;

	public InnerSocketBuilder(String target) {
		this("10.0.0.172", 80, target);
	}

	/**
	 * 建立经由代理服务器至目标服务器的连接
	 * 
	 * @param proxyHost
	 *            代理服务器地址
	 * @param proxyPort
	 *            代理服务器端口
	 * @param target
	 *            目标服务器
	 */
	public InnerSocketBuilder(String proxyHost, int proxyPort, String target) {
		this.proxyHost = proxyHost;
		this.proxyPort = proxyPort;
		this.target = target;
		connect();
	}

	private void connect() {
		future = new FutureTask<Socket>(
				new Callable<Socket>() {
			@Override
			public Socket call() throws Exception {
				try {

					BufferedReader din = null;
					BufferedWriter dout = null;
					innerSocket = new Socket(proxyHost, proxyPort);
					Logger.v(TAG, " :建立通道");
					innerSocket.setKeepAlive(true);
					innerSocket.setSoTimeout(30 * 1000);
					din = new BufferedReader(new InputStreamReader(
							innerSocket.getInputStream()));
					dout = new BufferedWriter(new OutputStreamWriter(
							innerSocket.getOutputStream()));
					String connectStr = "CONNECT " + target	+ " HTTP/1.1\r\nUser-agent: " + UA + "\r\n\r\n";

					dout.write(connectStr);
//					dout.newLine();
					dout.flush();

					String result = din.readLine();
					String line = "";
					while ((line = din.readLine()) != null) {
						if (line.trim().equals(""))
							break;
						Logger.v(TAG, line);
					}

					if (result != null && result.contains("200")) {
						Logger.v(TAG, result);
						Logger.v(TAG, "通道建立成功， 耗时："
								+ (System.currentTimeMillis() - starTime) / 1000);
						isConnected = true;
					} else {
						Logger.d(TAG, "建立隧道失败 :" + result);
					}

				} catch (IOException e) {
					Logger.e(TAG, "建立隧道失败：" + e.getLocalizedMessage(), e);
				}
				
				return isConnected ? innerSocket : null;
			}});
		new Thread(future, "buildInnerSocket").start();

	}

	public Socket getSocket() {
		Socket sc = null;
		try {
			sc = future.get(3, TimeUnit.SECONDS);
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			e.printStackTrace();
			Logger.d(TAG, "timeout........");
			isConnected = false;
			future.cancel(true);
		}
		return sc;
	}

	public boolean isConnected() {
		return this.isConnected;
	}

}
